import React, { useRef, useState, useEffect } from 'react';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import { UploadOutlined } from '@ant-design/icons';
import {
  Breadcrumb,
  Button,
  Card,
  Form,
  Input,
  Radio,
  message,
  Upload,
  Modal,
  Space,
} from 'antd';
import { Link } from 'react-router-dom';
import Channel from 'components/Channel';
import styles from './index.module.scss';
import { getToken } from 'utils/storage';
import { baseURL } from 'utils/request';
import {
  editArticlesDatailsAPI,
  getArticlesDatailsAPI,
  publishArticlesAPI,
} from 'api/articles';

export default function ArticlePublish(_props) {
  // 21.1 声明Formref
  const formRef = useRef();
  //13.1 声明ref
  const draftRef = useRef(false);
  //1,声明 type 的state
  const [type, setType] = useState(1);
  // 图片上传相关的
  const [imgSrc, setImgSrc] = useState('');
  //2.2声明状态控制Upload 的fileList 等价于表单的value
  const [fileList, setFileList] = useState([]);

  useEffect(() => {
    console.log(33, draftRef.current);
  }, []);
  //1,上传相关的提取了配置props
  const props = {
    //打开文件窗口时  可以默认显示文件类型
    accept: '.png,.jpg',
    //1.1 name代表后台支持上传文件的类型  值由后台决定
    name: 'image',
    //1.2 代表上传文件的请求url地址
    action: `${baseURL}/v1_0/upload`,
    //1.3 加上token 预防别人恶意上传 弄蹦服务器
    headers: {
      authorization: `Bearer ${getToken()}`,
    },

    // 2.1上传文件改变时的状态
    onChange(info) {
      // console.log(24, info);
      // 2.3 onChange事件改变fileList 并且 fileList 绑定在Upload 的props身上
      setFileList(info.fileList);

      //这个是复制的 没有用
      if (info.file.status !== 'uploading') {
        // console.log(info.file, info.fileList);
      }

      if (info.file.status === 'done') {
        message.success(`${info.file.name} 文件上传成功`);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 文件上传失败`);
      }
    },
    //点击小眼睛  放大
    // 22.4 回显数据 放按钮不生效 重新看一下file是url 做一个逻辑与
    onPreview(file) {
      console.log('11', file);
      setImgSrc(file.thumbUrl || file.url);
    },

    //1上传文件之前的钩子
    beforeUpload(file) {
      //2,判断file.type的值 阻止非图片的文件上传
      //白名单
      const imgs = ['image/jpg', 'image/png', 'image/jpeg'];

      //3,阻止图片上传
      if (!imgs.includes(file.type)) {
        message.warning('不允许上传的文件类型', 1);
        // Upload.LIST_IGNORE  阻止发起请求,也不在前端界面显示图片
        return Upload.LIST_IGNORE;
      }
    },
  };

  // Fomr	字段值更新时触发回调事件
  const handleValuesChange = (changeValues, allValue) => {
    // console.log(changeValues, allValue);
    //2.1 判断changeValuse 有type 这个属性 并且 不为undefined
    if (changeValues.type !== undefined) {
      setType(changeValues.type);
    }
  };
  // 8.1定义Upload 允许显示的数组 , 计算属性showFileList 代替 Upload的fileList
  const showFileList = fileList.filter((item, index) => {
    //如果type=0 返回false 代表空数组
    if (type === 0) return false;
    //如果type为1 , 返回条件 index===0, 代表返回一个元素的数组
    if (type === 1) return index === 0;
    //如果type 为 3 , 返回true , 代表整个数组
    return true;
  });

  /* 在显示位置改成一行代码 //3, 根据fileList 和type的值 做计算属性 showAddIco 显示上传的按钮
  const showAddIco = () => {
    //单图
    if (type === 1 && fileList.length >= 1) {
      return false;
    }
    //三图
    if (type === 3 && fileList.length >= 3) {
      return false;
    }
    // 无图
    if (type === 0) {
      return false;
    }
    return true;
  }; */

  // 提交
  const handleFinish = async (values) => {
    // 14.1
    if (showFileList.length !== type) {
      message.warning('封面张数不匹配');
      return;
    }
    // console.log('values', values);
    //1,按接口要求,拼接formData
    let formData = {
      ...values,
    };

    //组装 图片 给formData对象添加属性
    formData.cover = {
      type: values.type,
      //images 是url字符串组成的数组
      //14.2 fileLIst 变 showFileList 用计算好的
      //16.5  看item.respons有没有   有是在发布是  没有则是编辑 存item.url
      images: showFileList.map((item) =>
        item.respons ? item.response.data.url : item.url
      ),
    };
    //删除 formData 对象的属性
    delete formData.type;
    delete formData.test;

    // 16.2 提交是判断是否有id
    if (editId) {
      //16,3请求接口
      await editArticlesDatailsAPI(editId, formData, draftRef.current);
      //16,4 提示用户
      message.success('操作成功');
    } else {
      //1,请求接口
      await publishArticlesAPI(formData, draftRef.current);
      //2,提示用户
      message.success('操作成功');
    }

    //跳转路由
    _props.history.push('/list');
    // console.log('formData', formData);
  };

  //20.3接收 路由上的id
  // console.log(154, _props);
  const editId = _props.match.params.id;

  const loadEditArticle = async (editId) => {
    const res = await getArticlesDatailsAPI(editId);
    console.log(res);
    // 21.3 数据保存在formRef身上
    //22.1 type 重新回传进去
    formRef.current.setFieldsValue({ ...res.data, type: res.data.cover.type });
    //22.2 回填自定义的type状态的值  计算属性需要
    setType(res.data.cover.type);
    //22.3 回调fielList 注意是对象组成2的数组  这样就能显示图片
    setFileList(res.data.cover.images.map((item) => ({ url: item })));
  };

  // 20.4  页面加载是触发生命周期
  useEffect(() => {
    //判断有没有id 有就发请求 获取数据
    if (editId) {
      loadEditArticle(editId);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div
      className={styles.root}
      style={{ height: 'calc (100vh-64px)', overflow: 'auto', padding: 24 }}
    >
      <Card
        title={
          <Breadcrumb>
            <Breadcrumb.Item>
              <Link to="/home">首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>{editId ? '编制' : '发布'}文章</Breadcrumb.Item>
          </Breadcrumb>
        }
        bordered={false}
      >
        <Form
          // 21.2 表单绑定ref
          ref={formRef}
          name="basic"
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          autoComplete="off"
          size="middle"
          onFinish={handleFinish}
          initialValues={{ content: '', type: 1 }}
          onValuesChange={handleValuesChange}
        >
          <Form.Item
            label="标题"
            name="title"
            rules={[{ required: true, message: '请输入标题' }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[{ required: true, message: '请输入频道' }]}
          >
            <Channel allowClear></Channel>
          </Form.Item>
          <Form.Item
            label="内容"
            name="content"
            rules={[
              {
                message: '文章内容不能为空',
                //自定义检验 因为写了后删除会有<p><br></p> 不会触发检验 所以要自定义检验
                validator: (_, value) => {
                  // console.log('55value', value);
                  //判断value的值为  返回失败信息
                  //1,判断是否为空标签
                  //2, 使用自定义校验,返回 Promise.resolve()代表通过   Promise.reject()代表失败
                  if (value === '<p><br></p>') {
                    return Promise.reject(new Error('内容不能为空'));
                  }
                  return Promise.resolve();
                },
              },
              { required: true, message: '内容不能为空哦' },
            ]}
          >
            <ReactQuill theme="snow"></ReactQuill>
          </Form.Item>
          <Form.Item label="封面" name="type">
            <Radio.Group>
              <Radio value={1}>单图</Radio>
              <Radio value={3}>三图</Radio>
              <Radio value={0}>无图</Radio>
            </Radio.Group>
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 4 }} name="test">
            <Upload {...props} listType="picture-card" fileList={showFileList}>
              {/* 2.4  判断fileList 的数量  是否显示按钮*/}
              {fileList.length < type && <UploadOutlined />}
            </Upload>
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              <Button type="primary" htmlType="submit">
                {editId ? '编辑' : '发布'}
              </Button>
              {/* 13.2 给raftRef.current 赋值为true */}
              <Button
                htmlType="submit"
                onClick={() => (draftRef.current = true)}
              >
                存草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
      </Card>
      {/* 模态框 显示图片 */}
      <Modal
        title="预览图片"
        visible={!!imgSrc}
        onCancel={() => setImgSrc('')}
        footer={null}
      >
        <img width={480} style={{ objectFit: 'cover' }} src={imgSrc} alt="" />
      </Modal>
    </div>
  );
}
